日志显示
================

在我们的博客应用中，一篇日志可以显示在一个列表中，也可以单独显示。前者的实现通过 `index` 操作，而后者是通过 `view` 操作。 在这一节中，我们将自定义这两个操作来适合我们一开始的需求。


自定义 `view` 操作
----------------------------

`view` 操作是通过 `PostController` 中的  `actionView()` 方法实现的。它的显示是通过 `view` 视图文件 `/wwwroot/blog/protected/views/post/view.php` 生成的。

下面是在 `PostController` 中实现 `view` 操作的具体代码：

~~~
[php]
public function actionView()
{
	$post=$this->loadModel();
	$this->render('view',array(
		'model'=>$post,
	));
}

private $_model;

public function loadModel()
{
	if($this->_model===null)
	{
		if(isset($_GET['id']))
		{
			if(Yii::app()->user->isGuest)
				$condition='status='.Post::STATUS_PUBLISHED
					.' OR status='.Post::STATUS_ARCHIVED;
			else
				$condition='';
			$this->_model=Post::model()->findByPk($_GET['id'], $condition);
		}
		if($this->_model===null)
			throw new CHttpException(404,'The requested page does not exist.');
	}
	return $this->_model;
}
~~~

我们的修改主要是在 `loadModel()` 方法上进行的。在这个方法中，我们通过   `id` GET参数查询了 `Post` 表。如果日志未找到或者没有发布，也未存档(当用户为游客（guest）时)，我们将抛出一个 404 HTTP 错误。否则，日志对象将返回给 `actionView()` ，`actionView()` 又会把日志对象传递给视图脚本用于显示。

> Tip|提示: Yii 会捕获 HTTP 异常 ([CHttpException] 的实例) 并通过预置的模板或自定义的错误视图显示出来。由 `yiic` 生成的程序骨架已经包含了一个自定义的错误视图 `/wwwroot/blog/protected/views/site/error.php`。如果想进一步自定义此错误显示，我们可以自己修改此文件。

`view` 脚本中的修改主要是关于调整日志显示格式和样式的。此处我们不再细讲，读者可以参考 `/wwwroot/blog/protected/views/post/view.php`.


自定义 `index` 操作
----------------------------

和 `view` 操作类似，我们在两处自定义 `index` 操作：`PostController` 中的 `actionIndex()` 方法和视图文件 `/wwwroot/blog/protected/views/post/index.php`。我们主要需要添加对显示一个特定Tag下的日志列表的支持；

下面就是在 `PostController` 中对 `actionIndex() 方法作出的修改:

~~~
[php]
public function actionIndex()
{
	$criteria=new CDbCriteria(array(
		'condition'=>'status='.Post::STATUS_PUBLISHED,
		'order'=>'update_time DESC',
		'with'=>'commentCount',
	));
	if(isset($_GET['tag']))
		$criteria->addSearchCondition('tags',$_GET['tag']);

	$dataProvider=new CActiveDataProvider('Post', array(
		'pagination'=>array(
			'pageSize'=>5,
		),
		'criteria'=>$criteria,
	));

	$this->render('index',array(
		'dataProvider'=>$dataProvider,
	));
}
~~~

在上面的代码中，我们首先为检索日志列表创建了一个查询标准（criteria），此标准规定只返回已发布的日志，且应该按其更新时间倒序排列。因为我们打算在显示日志列表的同时显示日志收到的评论数量，因此在这个标准中我们还指定了要带回 `commentCount`, 如果你还记得，它就是在 `Post::relations()` 中定义的一个关系。

考虑到当用户想查看某个Tag下的日志列表时的情况，我们还要为指定的Tag添加一个搜索条件到上述标准中。

使用这个查询标准，我们创建了一个数据提供者（data provider）。这主要出于三个目的。第一，它会在查询结果过多时实现数据分页。这里我们定义分页的页面大小为5。 第二，它会按用户的请求对数据排序。最后，它会填充排序并分页后的数据到小部件(widgets)或视图代码用于显示。

完成 `actionIndex()` 后，我们将 `index` 视图修改为如下代码。 此修改主要是关于在用户指定显示Tag下的日志时添加一个 `h1` 标题。

~~~
[php]
<?php if(!empty($_GET['tag'])): ?>
<h1>Posts Tagged with <i><?php echo CHtml::encode($_GET['tag']); ?></i></h1>
<?php endif; ?>

<?php $this->widget('zii.widgets.CListView', array(
	'dataProvider'=>$dataProvider,
	'itemView'=>'_view',
	'template'=>"{items}\n{pager}",
)); ?>
~~~

注意上面的代码，我们使用了 [CListView] 来显示日志列表。这个小物件需要一个局部视图以显示每一篇日志的详情。这里我们制定了局部视图为 `_view`，也就是文件 `/wwwroot/blog/protected/views/post/_view.php`. 在这个视图脚本中，我们可以通过一个名为 `$data` 的本地变量访问显示的日志实例。

<div class="revision">$Id: post.display.txt 2121 2010-05-10 01:31:30Z qiang.xue $</div>